package com.linzm.leetcode.primary.exercises4_20230129;

/**
 * @Author zimingl
 * @Date 2023/1/29 23:00
 * @Description: 亲密字符串
 */
public class Demo3_859 {
    /**
     * 给你两个字符串 s 和 goal ，只要我们可以通过交换 s 中的两个字母得到与 goal 相等的结果，就返回 true ；否则返回 false 。
     * 交换字母的定义是：取两个下标 i 和 j （下标从 0 开始）且满足 i != j ，接着交换 s[i] 和 s[j] 处的字符。
     * 例如，在 "abcd" 中交换下标 0 和下标 2 的元素可以生成 "cbad" 。
     * 输入：s = "ab", goal = "ba"
     * 输出：true
     * 解释：你可以交换 s[0] = 'a' 和 s[1] = 'b' 生成 "ba"，此时 s 和 goal 相等。
     * 输入：s = "ab", goal = "ab"
     * 输出：false
     * 解释：你只能交换 s[0] = 'a' 和 s[1] = 'b' 生成 "ba"，此时 s 和 goal 不相等。
     * 输入：s = "aa", goal = "aa"
     * 输出：true
     * 解释：你可以交换 s[0] = 'a' 和 s[1] = 'a' 生成 "aa"，此时 s 和 goal 相等。
     */
    public static void main(String[] args) {
        Demo3_859 demo3_859 = new Demo3_859();
        String s = "ab", goal = "ba";
        boolean buddyStrings = demo3_859.buddyStrings(s, goal);
        System.out.println(buddyStrings);
    }

    public boolean buddyStrings(String s, String goal) {
        if (s.length() != goal.length() && s.length() <= 1) {
            return false;
        }
        char[] sArr = s.toCharArray();
        char[] goalArr = goal.toCharArray();
        int[] arr = new int[2];
        int index = 0;
        for (int i = 0; i < sArr.length; i++) {
            if (sArr[i] != goalArr[i]) {
                arr[index++] = i;
            }
            if (index > 2) {
                return false;
            }
        }
        int count = 0;
        if (s.equals(goal)) {
            for (int i = 0; i < sArr.length - 1; i++) {
                if (sArr[i] == goalArr[i]) {
                    count++;
                }
            }
        }
        if (count == sArr.length - 1) {
            return true;
        }
        if (index == 1) {
            return false;
        }
        if (index == 2 && sArr[arr[0]] == goalArr[arr[1]] && sArr[arr[1]] == goalArr[arr[0]]) {
            return true;
        }
        return false;
    }

    private void swap(char[] arr, int i, int j) {
        char tmp = arr[i];
        arr[i] = arr[j];
        arr[j] = tmp;
    }

    public boolean buddyStrings2(String s, String goal) {
        if (s.length() != goal.length() && s.length() == 1) {
            return false;
        }
        // 两字符串相等的case
        if (s.equals(goal)) {
            int[] count = new int[26];  // 建立一个26个字母的索引
            for (int i = 0; i < s.length(); i++) {
                count[s.charAt(i) - 'a']++;   // 对应字母频度统计
                if (count[s.charAt(i) - 'a'] > 1) {   // 如果有大于1的，就一定有重复字母，因为两字符串相等，所以换重复的就一定相等
                    return true;
                }
            }
            return false;
        } else {
            // 两字符串不相等的情况
            int first = -1, second = -1;
            int[] arr = new int[2];
            for (int i = 0; i < goal.length(); i++) {  // 遍历字符串
                if (s.charAt(i) != goal.charAt(i)) {  // 判断有且仅有两个s和goal相同位置的字符不一样，一个first, 一个second
                    if (first == -1)
                        first = i;   // 找到first
                    else if (second == -1)
                        second = i;   // 找到second
                    else
                        return false;   // 超过两个
                }
            }
            //second != -1 first也就不是-1了，满足有且仅有两个不同字符
            //s的first等于goal的second且s的second等于goal的first,互换可得相同字符串
            return (second != -1 && s.charAt(first) == goal.charAt(second) &&
                    s.charAt(second) == goal.charAt(first));
        }
    }
}
